PROGRAM Lists;

  TYPE ListNodePtr = ^ListNode;
    ListNode = RECORD 
      next: ListNodePtr;
      data: INTEGER;
    END;
    ListPtr = ListNodePtr;

  VAR list: ListPtr;

  FUNCTION EmptyList: ListPtr;
  BEGIN 
    EmptyList := NIL;
  END;

  FUNCTION NewListNode(data: INTEGER): ListNodePtr;
    VAR n: ListNodePtr;
  BEGIN 
    New(n);
    IF n = NIL THEN BEGIN 
      WriteLn('error: heap overflow');
      HALT;
    END ;
    n^.next := NIL;
    n^.data := data;
    NewListNode := n;
  END;

  PROCEDURE Prepend(VAR list: ListPtr; n: ListNodePtr);
  BEGIN 
    n^.next := list;    (* 1. append old list to new node*)
    list := n;  (* 2. new list = ( n, old list )*)
  END;

  PROCEDURE Append(VAR list: ListPtr; n: ListNodePtr);
    VAR last: ListNodePtr;
  BEGIN 
    IF list = NIL THEN BEGIN       (* list is empty*)
      list := n;
    END ELSE BEGIN       (* list != null, list is not empty*)
      (* search last node*)
      last := list;
      WHILE last^.next <> NIL DO BEGIN 
        last := last^.next;
      END;      (* while*)
      (* append n to last node*)
      last^.next := n;    (* new list = ( old list, n )*)
    END;  (* if*)
  END;

  PROCEDURE WriteList(l: ListPtr);
    VAR n: ListNodePtr;
  BEGIN 
    n := l;
    WriteLn('write list:');
    WHILE n <> NIL DO BEGIN 
      WriteLn('element<', n^.data, '>');
      n := n^.next;
    END;
  END;

BEGIN 
  list := EmptyList();
  Prepend(VAR list, NewListNode(5));
  Prepend(VAR list, NewListNode(4));
  Append(VAR list, NewListNode(6));
  WriteList(list);
  ReadLn();
END.